package com.ruoyi.bim.controller;

import com.alibaba.druid.support.json.JSONUtils;
import com.onelogin.saml2.Auth;
import com.onelogin.saml2.exception.Error;
import com.onelogin.saml2.exception.SettingsException;
import com.onelogin.saml2.exception.XMLEntityException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.shiro.token.LoginType;
import com.ruoyi.framework.shiro.token.UserToken;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Controller
@RequestMapping("/bimService")
public class BAMSAMLController {
    @Value("${oauth.clientId}")
    private String clientId;
    @Value("${oauth.clientSecret}")
    private String clientSecret;
    @Value("${oauth.bamDomain}")
    private String bamDomain;

    @RequestMapping("/samlLogin")
    public void samlLogin(HttpServletRequest request,
                            HttpServletResponse response) throws IOException {
        try {
            Auth auth = new Auth(request, response);
            auth.login();
        } catch (SettingsException e) {
            e.printStackTrace();
        } catch (Error error) {
            error.printStackTrace();
        }
    }

    @RequestMapping("/samlACS")
    public String samlACS(HttpServletRequest request,
                          HttpServletResponse response, HttpSession session) throws IOException {
        Auth auth = null;
        try {
            auth = new Auth(request, response);
            auth.processResponse();
            if (!auth.isAuthenticated()) {
                return "error/unauth";
            }
            List<String> errors = auth.getErrors();
            if (!errors.isEmpty()) {
                String errorsStr = StringUtils.join(errors, ", ");
                if (auth.isDebugActive()) {
                    String errorReason = auth.getLastErrorReason();
                    if (errorReason != null && !errorReason.isEmpty()) {
                        String lastErrorReasonStr = auth.getLastErrorReason();
                        return "error/unauth";
                    }
                }
            }else{
                Map<String, List<String>> attributes = auth.getAttributes();
                String nameId = auth.getNameId();
                String nameIdFormat = auth.getNameIdFormat();
                String sessionIndex = auth.getSessionIndex();
                String nameidNameQualifier = auth.getNameIdNameQualifier();
                String nameidSPNameQualifier = auth.getNameIdSPNameQualifier();

                session.setAttribute("attributes", attributes);
                session.setAttribute("nameId", nameId);
                session.setAttribute("nameIdFormat", nameIdFormat);
                session.setAttribute("sessionIndex", sessionIndex);
                session.setAttribute("nameidNameQualifier", nameidNameQualifier);
                session.setAttribute("nameidSPNameQualifier", nameidSPNameQualifier);

                Subject subject = SecurityUtils.getSubject();
//                List<String> strings = attributes.get("urn:oid:spRoleList-OID");
//                String userName = Objects.toString(strings.get(0),"");
//                UserToken usernamePasswordToken = new UserToken(userName, LoginType.NOPASSWD);
                UserToken usernamePasswordToken = new UserToken(nameId, LoginType.NOPASSWD);
                try {
                    subject.login(usernamePasswordToken);
                    return "OAuth2Index";
                } catch (AuthenticationException e) {
                    return "error/unauth";
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    @RequestMapping("/samlSLS")
    public void samlSLS(HttpServletRequest request,
                          HttpServletResponse response,HttpSession session) throws IOException {
        Auth auth = null;
        try {
            auth = new Auth(request, response);
        } catch (SettingsException e) {
            e.printStackTrace();
        } catch (Error error) {
            error.printStackTrace();
        }

        String nameId = null;
        if (session.getAttribute("nameId") != null) {
            nameId = session.getAttribute("nameId").toString();
        }
        String nameIdFormat = null;
        if (session.getAttribute("nameIdFormat") != null) {
            nameIdFormat = session.getAttribute("nameIdFormat").toString();
        }
        String nameidNameQualifier = null;
        if (session.getAttribute("nameidNameQualifier") != null) {
            nameIdFormat = session.getAttribute("nameidNameQualifier").toString();
        }
        String nameidSPNameQualifier = null;
        if (session.getAttribute("nameidSPNameQualifier") != null) {
            nameidSPNameQualifier = session.getAttribute("nameidSPNameQualifier").toString();
        }
        String sessionIndex = null;
        if (session.getAttribute("sessionIndex") != null) {
            sessionIndex = session.getAttribute("sessionIndex").toString();
        }
        try {
            auth.logout(null, nameId, sessionIndex, nameIdFormat, nameidNameQualifier, nameidSPNameQualifier);
        } catch (XMLEntityException e) {
            e.printStackTrace();
        } catch (SettingsException e) {
            e.printStackTrace();
        }
    }
}
